package com.gardeneaters.game_v0.rules;

import java.util.Vector;

import com.gardeneaters.game_v0.playingfield.Hexagon;

//power of hexagon
class Power extends Hexagons{
	
	protected Power(Hexagon[][] _hexagons) {
		super(_hexagons);
		
	}
	
	private void calculatePowerOfHeads(Vector<int[]> headPositions){
		
		int [] temp;
		for(int i=0; i<headPositions.size(); i++)
		{
			temp = headPositions.elementAt(i);
			if(!isInLoop(temp[0],temp[1]))
				calculateHeadPower(temp[0],temp[1], Double.MAX_VALUE);
			else
				calculateLoopPower(temp[0],temp[1]);
		}
			
		//power of all heads has been calculated.. 
		// now re-calculate power of those hex which are under attack
		// hexagons can be attacked by heads only
		int pointingTo;
		Hexagon tempHex;
		int [] tempPos;
		for(int i=0; i<headPositions.size(); i++)
		{
			temp = headPositions.elementAt(i);
			pointingTo = hexagons[temp[0]][temp[1]].getPointingTo();
			tempHex = getHexagon(pointingTo, temp[0], temp[1]);
			if(tempHex==null)
				continue;
			tempPos = getHexagonPos(pointingTo, temp[0], temp[1]);
			if(isUnderAttack(tempPos[0], tempPos[1]))
				reCalculatePower(tempPos[0], tempPos[1]);
		}
		
	}

	private void reCalculatePower(int i, int j) {
		// re-calculates power of hex which is under attack
		//System.out.println("recalculationg for "+i+" "+j);
		Hexagon tempHex;
		int team = hexagons[i][j].getTeam();
		
		Vector <PowerCalculator> powerVector = new Vector<PowerCalculator>();
		PowerCalculator tempPowCal;
		int teamPos;
		for(int k=0; k<7; k++)
		{
			if(isPointingAtMe(k, i, j))
			{
				tempHex = getHexagon(k, i, j);
				if(tempHex.getTeam() != team)
				{
					teamPos=-1;
					for(int l =0; l<powerVector.size(); l++)
					{
						if(powerVector.elementAt(l).getTeam()==tempHex.getTeam())
							teamPos = l;
					}
					
					if(teamPos==-1)
					{
						tempPowCal = new PowerCalculator(tempHex.getTeam());
						powerVector.add(tempPowCal);
					}
					else
					{
						tempPowCal = powerVector.elementAt(teamPos);
					}
					
					tempPowCal.addHex(tempHex.getCurrentPow());
					
				}
			}
		}
		
		int tempTeam = team;
		double maxPow=0;
		double tempPow;
		if(powerVector.size()>=1)
		{
			maxPow = powerVector.elementAt(0).getPower();
			tempTeam = powerVector.elementAt(0).getTeam();
			for(int k=1; k<powerVector.size(); k++)
			{
				tempPow = powerVector.elementAt(k).getPower();
				if(Double.compare(tempPow, maxPow)==1)
				{
					maxPow = tempPow;
					tempTeam = powerVector.elementAt(k).getTeam();
				}
			}
		}
		double finalPow;
		if(hexagons[i][j].getTeam()==0)
			finalPow = maxPow;
		else
			finalPow = hexagons[i][j].getFinalPower() - maxPow;
		//System.out.println("calculated finalPow "+finalPow+ " previous FinalPow "+hexagons[i][j].getFinalPower()+" maxPow "+maxPow+" currentPow "+hexagons[i][j].getCurrentPow()+" tempTeam "+tempTeam+" actual team "+hexagons[i][j].getTeam());
		hexagons[i][j].setFinalPow(finalPow);
		//TODO it continuously alternates teams in the end.. correct it
		
			if(hexagons[i][j].getTeam()==0 )
				hexagons[i][j].setTeam(tempTeam,false);
			else if(Double.compare(0.1, hexagons[i][j].getCurrentPow())==1 && Double.compare(0.1, finalPow)==1)
				hexagons[i][j].setTeam(0,false);
		
	}

	private void calculateLoopPower(int i, int j) {

		//hexagons[i][j].calculating=true;
		
			int tempPos [];
			int numOfHexPointingAtLoop=0;
			int numOfHexInLoop=0;
			int team = hexagons[i][j].getTeam();
			double finalPow=0;
			int pointingTo;
			int[] nextPos = new int[2];
			nextPos[0]=i;
			nextPos[1]=j;
			
			//finalPow= hexagons[i][j].getCurrentPow();
	
			do{
				
				for(int k =1; k<7; k++)
				{
					if(isPointingAtMe(k, nextPos[0], nextPos[1]))
					{
						tempPos = getHexagonPos(k, nextPos[0], nextPos[1]);
						
						if(!isInLoop(tempPos[0],tempPos[1]) && hexagons[tempPos[0]][tempPos[1]].getTeam()==team)
						{
							//System.out.println("Not in Loop");
							calculateHeadPower(tempPos[0],tempPos[1],Double.MAX_VALUE);
							finalPow += hexagons[tempPos[0]][tempPos[1]].getCurrentPow();
							numOfHexPointingAtLoop++;
						}
					}
				}
				
				pointingTo = hexagons[nextPos[0]][nextPos[1]].getPointingTo();
				nextPos = getHexagonPos(pointingTo, nextPos[0], nextPos[1]);
				numOfHexInLoop++;
			}while( i!= nextPos[0] || j!=nextPos[1] );
			
			
			/*
			 * Normal Head formula was a+b+c+0.3n-n+1
			 * Loop Head formula is a+b+c+0.3n-n+1+ [Summation of k from 1 to l-1]*0.3/l
			 * Simplified to a+b+c+0.3n-n+1 + (l-1)*0.3/2
			 * n is numOfHexPointingAtLoop
			 * l is numOfHexInLoop
			 */
			finalPow += 0.3*numOfHexPointingAtLoop - numOfHexPointingAtLoop; //+ 1 + (numOfHexInLoop-1)*0.15;
			// following condition is used coz when newborn hex starts pointing at Loop it appears to withdraw power
			if(finalPow<0)
				finalPow=0;
			finalPow += 1 + (numOfHexInLoop-1)*0.15;

			
			nextPos[0]=i;
			nextPos[1]=j;
			do{
				hexagons[nextPos[0]][nextPos[1]].setFinalPow(finalPow);
				pointingTo = hexagons[nextPos[0]][nextPos[1]].getPointingTo();
				nextPos = getHexagonPos(pointingTo,nextPos[0], nextPos[1]);
				//numOfHexInLoop++;
			}while( i!= nextPos[0] || j!=nextPos[1] );
			
		//hexagons[i][j].calculating = false;
		
	}

	private void calculateHeadPower(int i, int j, double powOfAttacked){
		
		int [] tempPos;
		int team = hexagons[i][j].getTeam();
		int pointingHexTeam;
		double FinalPow=1;
		//boolean flag=false;
		double tempPow;
		//int numOfHexPointingToMe=0;
		PowerCalculator powerCal = new PowerCalculator();
		for(int k =1; k<7; k++)
		{
			if(isPointingAtMe(k, i, j))
			{
			//	flag=true;
				tempPos = getHexagonPos(k, i, j);
				pointingHexTeam = hexagons[tempPos[0]][tempPos[1]].getTeam();
				if( pointingHexTeam==team)// || team ==0 )
				{
//					if(hexagons[i][j].getTeam()==0)
//					{
//						hexagons[i][j].setTeam(hexagons[tempPos[0]][tempPos[1]].getTeam(),false);
//					}
					calculateHeadPower(tempPos[0],tempPos[1],hexagons[i][j].getCurrentPow());
					tempPow = hexagons[tempPos[0]][tempPos[1]].getCurrentPow();
					powerCal.addHex(tempPow);
					//FinalPow += tempPow;// calculates (a+b+c)
					//numOfHexPointingToMe++;
				}
			}
		}
		//if(flag)
		//{			/* the actual calculation is (a+b+c) + 0.3*n +(-1)*n +1
		//	   		it means (a-1)+(b-1)+(c-1) + 0.3*n +1    */
		//	FinalPow += numOfHexPointingToMe*0.3 - numOfHexPointingToMe ;
		//}
		FinalPow = powerCal.getPower();
		//TODO i think u should add if(finalPow<1) then finalPow=1 statement here

		
		// to show as if a block is injecting power.. by first decreasing power and then back to normal
		//if(powOfAttacked<FinalPow)
		//	FinalPow -= (FinalPow-powOfAttacked)/2;
		
		if(FinalPow<1)
			FinalPow=1;
		
		hexagons[i][j].setFinalPow(FinalPow);
			
	}

	protected void update(Vector<int[]> headPositions) {
		
		calculatePowerOfHeads(headPositions);
		
	}
}
